﻿using BitShuva.Common;
using BitShuva.Models;
using Raven.Client;
using Raven.Client.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace BitShuva.Controllers
{
    [RoutePrefix("api/albums")]
    public class AlbumsController : UserContextController
    {
        /// <summary>
        /// Uploads the album art for a song. The album art will be applied to all songs matching the artist and album.
        /// </summary>
        /// <param name="address">The HTTP address where the album art can be fetched. This is expected to be a temporary address created by FilePickr.</param>
        /// <param name="fileName">The file name. Used for extracting the extension.</param>
        /// <param name="artist">The artist this album art applies to.</param>
        /// <param name="album">The name of the album this album art applies to.</param>
        [HttpPost]
        [Route("uploadArt")]
        public async Task<Album> UploadAlbumArt(string address, string fileName, string artist, string album)
        {
            var downloader = new System.Net.WebClient();
            var unescapedFileName = Uri.UnescapeDataString(artist) + " - " + Uri.UnescapeDataString(album) + Path.GetExtension(fileName);

            var albumArtUri = await CdnManager.UploadAlbumArtToCdn(artist, album, new Uri(address), Path.GetExtension(fileName));
            var existingAlbum = await this.Session
                .Query<Album>()
                .FirstOrDefaultAsync(a => a.Artist == artist && a.Name == album);
            if (existingAlbum != null)
            {
                existingAlbum.AlbumArtUri = albumArtUri;
            }
            else
            {
                existingAlbum = new Album
                {
                    Name = album,
                    Artist = artist,
                    AlbumArtUri = albumArtUri
                };
                await this.Session.StoreAsync(existingAlbum);
            }

            // Update the songs on this album.
            var songsOnAlbum = await this.Session
                .Query<Song>()
                .Where(s => s.Artist == artist && s.Album == album)
                .ToListAsync();
            songsOnAlbum.ForEach(s => s.AlbumArtUri = albumArtUri);

            return existingAlbum;
        }

        /// <summary>
        /// Find album art wit the specified artist and album name.
        /// </summary>
        /// <param name="songId">The ID of the song we're checking for.</param>
        /// <param name="artist">The artist name.</param>
        /// <param name="album">The album.</param>
        /// <returns>An Album-like object containing the ID of the song.</returns>
        [Route("art/{songId}/{artist}/{album}")]
        public async Task<dynamic> GetAlbumArt(string songId, string artist, string album)
        {
            var existingAlbum = await this.Session
                .Query<Album>()
                .FirstOrDefaultAsync(a => a.Artist == artist && a.Name == album);
            return new
            {
                SongId = songId,
                Artist = Match.Value(existingAlbum).PropertyOrDefault(a => a.Artist),
                Name = Match.Value(existingAlbum).PropertyOrDefault(a => a.Name),
                AlbumArtUri = Match.Value(existingAlbum).PropertyOrDefault(a => a.AlbumArtUri)
            };
        }
    }
}
